package cn.geminis.lowcode.compiler.code;

import cn.geminis.lowcode.compiler.util.JdkTreeMakerUtils;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.Tree;
import lombok.NonNull;

import javax.lang.model.element.ExecutableElement;
import java.util.List;
import java.util.Objects;

/**
 * @author puddi
 */
public class LcMethod extends AbstractCode<MethodTree, ExecutableElement> {
    private final LcModifier modifiers;
    private final String returnType;
    private final List<String> returnTypeParameters;
    private final String name;
    private final List<LcVariable> params;
    private final List<String> throwTypes;
    private final List<AbstractStatement<?>> body;

    public LcMethod(
            @NonNull LcModifier modifiers,
            String returnType,
            List<String> returnTypeParameters,
            String name,
            @NonNull List<LcVariable> params,
            @NonNull List<String> throwTypes,
            List<AbstractStatement<?>> body
    ) {
        this.modifiers = modifiers;
        this.returnType = returnType;
        this.returnTypeParameters = returnTypeParameters;
        this.name = name;
        this.params = params;
        this.throwTypes = throwTypes;
        this.body = body;
    }

    public LcMethod(
            @NonNull LcModifier modifiers,
            String returnType,
            String name,
            @NonNull List<LcVariable> params,
            @NonNull List<String> throwTypes,
            List<AbstractStatement<?>> body
    ) {
        this(
                modifiers,
                returnType,
                List.of(),
                name,
                params,
                throwTypes,
                body
        );
    }

    @Override
    protected MethodTree createJdkTree() {
        return JdkTreeMakerUtils.methodDef(
                this.modifiers.getJdkTree(),
                name,
                returnType,
                returnTypeParameters,
                params.stream().map(LcVariable::createJdkTree).toList(),
                throwTypes,
                Objects.isNull(body) ? null : JdkTreeMakerUtils.block((List<Tree>) body.stream().map(AbstractCode::createJdkTree).toList())
        );
    }

    @Override
    protected ExecutableElement createJdkElement() {
        throw new UnsupportedOperationException();
    }
}
